'use strict'
const fs = require('fs')
const path = require('path')

const TEMPLATE_ROOT = path.normalize('./template')
const OUT_ROOT = path.normalize('../../src/game/module')

const Module_Name = 'm'
const View_Name = 'v'
const PROCESS_ARGV = {m:'',v:''}

const ReplaceKeyReg_ModuleName = /\$\{ModuleName\}/mg
const ReplaceKeyReg_ViewName = /\$\{ViewName\}/mg
const RegClassName = /export class (.+?) extends/

dealArgv();
main();

function dealArgv(){
    var pArgv = process.argv;
    var keys = Object.keys(PROCESS_ARGV);
    for( var i = keys.length - 1; i >= 0; i-- ){
        var key = keys[ i ];
        var cliKey = '-'+key;
        var cliIndex = pArgv.indexOf(cliKey)
        if(cliIndex>=0){
            PROCESS_ARGV[key] = pArgv[cliIndex+1]
        }
    }
}
function getArg(key){
    return PROCESS_ARGV[key];
}
function main(){
    var moduleName = getArg(Module_Name);
    var viewName = getArg(View_Name);
    if(moduleName=='' || viewName==''){
        warn('please enter -m and -v')
        return;
    }
    var outModulePath = path.join(OUT_ROOT, moduleName)
    fs.access(outModulePath, function(aomErr){//make sure out directory exist
        if(aomErr){
            fs.mkdir(outModulePath, function(momErr){
                if(momErr){
                    warn(momErr)
                }else{
                    dealTemplate(moduleName, viewName)
                }
            })
        }else{
            dealTemplate(moduleName, viewName)
        }
    })
}

function dealTemplate(mName, vName){
    recursiveFiles(TEMPLATE_ROOT, function(file){
        var outFile = changeRoot(TEMPLATE_ROOT, file, path.join(OUT_ROOT,mName));
        var outFileObj = path.parse(outFile);
        var prefix = outFileObj.name == 'Model' ? mName : vName
        prefix = prefix.charAt(0).toUpperCase()+prefix.slice(1);
        outFile = path.join(outFileObj.dir, prefix+outFileObj.name)
        outFile += '.ts'
        fs.open(outFile, 'wx', function(err, outFd){
            //已有的文件不做改动
            if(!(err && err.code === 'EEXIST')){
                fs.readFile(file, 'utf8', getWarnErr(function(templateStr){
                    var outStr = templateStr.replace(ReplaceKeyReg_ModuleName, mName);
                    outStr = outStr.replace(ReplaceKeyReg_ViewName, vName);
                    outStr = outStr.replace(RegClassName, function(matchStr, ...args){//类名大写
                        var className = args[0];
                        return matchStr.replace(className, className.charAt(0).toUpperCase() + className.slice(1));
                    })
                    var outBuf = new Buffer(outStr)
                    fs.write(outFd, outBuf, 0, outBuf.length, 0, getWarnErr())
                    fs.close(outFd, getWarnErr());
                }))
            }else if(outFd){
                fs.close(outFd, getWarnErr())
            }
        })
    },function(dir){
        var outDir = changeRoot(TEMPLATE_ROOT, dir, path.join(OUT_ROOT, mName));
        try{//这里得用同步方式，以确保文件夹创建
            fs.accessSync(outDir)
        }catch (dirErr) {
            fs.mkdirSync(outDir)
        }
    })
}
function recursiveFiles(file, dealFile, dealDir){
    fs.stat(file, getWarnErr(function(st){
        if(st.isDirectory()){
            dealDir(file)
            fs.readdir(file, getWarnErr(function(children){
                var len = children.length;
                for(var i=0; i<len; i++){
                    recursiveFiles(path.join(file,children[i]), dealFile, dealDir)
                }
            }))
        }else{
            dealFile(file)
        }
    }))
}

function changeRoot(sourceRoot, sourcePath, targetRoot){
    var childPath = sourcePath.slice(sourceRoot.length)
    return path.join(targetRoot, childPath);
}

function getWarnErr(resolve){
    return function(err, ...values){
        if(err){
            warn(err)
        }else if(resolve){
            resolve.apply(this, values)
        }
    }
}

function log(content){
    console.log(content);
}
function warn(content){
    console.warn(content);
}